import numpy as np

np.pi = 3.14159
import math
import os

public_ds = [
    25, 32, 36, 40, 50, 75
]
public_across_area = [491, 804, 1018, 1257, 1963, 4418
                      ]

real_croass_area_ = [
    0.94, 0.95, 0.95, 0.95, 0.95, 0.94
]
ideal_public_area = [
    522.3, 846.3, 1071.6, 1323.2, 2066.3, 4700
]


def cal_tuk2(
        LD,
        D2,
        soil_layer_fmgs,
        soil_layer_sizes,

):
    tuk2 = 0
    lldd = LD
    i = 0
    while lldd > 0:
        if lldd >= soil_layer_sizes[i]:
            tuk2 += soil_layer_fmgs[i] * D2 * soil_layer_sizes[i] / 1000
        else:
            tuk2 += soil_layer_fmgs[i] * D2 * lldd / 1000
        lldd -= soil_layer_sizes[i]
        i += 1
    return tuk2

def split_layer(h, soil_layer_sizes):
    #将土层分成两组，返回两个子土层数组
    sum_h = 0
    edge_index = 0
    for index, s in enumerate(soil_layer_sizes):
        sum_h += s
        if sum_h >= h:
            edge_index = index
            break
    sub_layer0 = soil_layer_sizes[:edge_index+1]
    sub_layer0[-1] = h - sum(sub_layer0[:-1])
    sub_layer1 = soil_layer_sizes[edge_index:]
    sub_layer1[-1] = sum(sub_layer0) - h
    return edge_index, sub_layer0, sub_layer1

    pass

def general(
        Pk=46,
        S1=3.9,
        S2=3.9,
        K=2,
        fpyk=1080,
        fms=2.2,
        D2=500,
        zeta0=35,
        with_delta_S=True
      ):

    Nak = Pk * S1 * S2
    print(f'Step1： Nak = p_k * s1 * s2 \n'
          f'\tNak = {Nak}\n')
    Tak = 1000 * Nak
    print(f'Step2： Tak = 1000 * Nak \n'
          f'\tTak = {Tak}\n')
    Tuk = K * Tak / 1000
    print(f'Step3： Tuk = K * Tak / 1000 \n'
          f'\tTuk = {Tuk}\n')
    A_s1 = 2 * Tak / fpyk
    print(f'Step4： A_s1 = 2 * Tak / fpyk \n'
          f'\tA_s1 = {A_s1}\n')
    d = 0
    for index, aa in enumerate(public_across_area):
        if aa >= A_s1:
            d = public_ds[index]
            break
    print('Step5：根据表格选取对应的公称直径d\n'
          f'\td = {d}\n')
    lD1 = Tuk / (np.pi * d * fms)
    print("Step6：计算lD1\n"
          f"\tlD1 = {lD1}")
    # delta_S = np.tanh(45 + zeta0 / 2) * (D2 / 2 - d / 2) / 1000
    delta_S = np.tan(np.radians(45)+np.radians(zeta0)/2)*(D2/2-d/2)/1000
    print(f"\tΔs = {delta_S}")
    if delta_S<0.5:
        delta_S = 0.5
        print("\tΔs < 0.5, 所以Δs = 0.5")
    if with_delta_S:
        LD1 = lD1 + delta_S
    else:
        LD1 = lD1
    LD1 = max(2, LD1)
    return Tuk, LD1, d

def cal_pd(zeta, gama, h, c, a):
    ka = np.tan((45 - zeta / 2) * np.pi / 180) ** 2
    # kp = np.tan(np.deg2rad(45 + zeta / 2))
    kp = np.tan(np.radians(45 + zeta / 2)) ** 2
    # k0 = 1 - np.sin(zeta)
    k0 = 1 - np.sin(np.radians(zeta))
    keze = a * ka
    print(f"\tka={ka} \n \tkp={kp} \n \tk0={k0} \n \tζ={keze}\n")

    print("step9 计算PD")
    PD = ((k0 - keze) * kp * gama * h + 2 * c * np.sqrt(kp)) / (1 - keze * kp)
    return PD
    pass


def anchor_design_1(
        A=1281.4,
        Pk=46,
        S1=3.9,
        S2=3.9,
        K=2,
        fpyk=1080,
        fms=2.2,
        h=5,
        a=0.85,
        D1=200,
        D2=500,
        zeta0=35,
        soil_layer_fmgs=[50, 90, 260, 260, 260],
        soil_layer_sizes=[1.3, 2, 1, 2.5, 4.9],
        soil_layer_zetas=[20, 25, 30, 35, 36],
        soil_layer_cs=[0, 0, 0, 0, 260],
        soil_layer_gamas=[19.5, 20.5, 21, 22, 23]
):
    #拉压型锚杆设计
    print("*****当前输入参数*****")
    print(f"抗浮面积A={A}")
    print(f"单位所需净抗浮力Pk={Pk}")
    print(f"锚杆横向间距（m）={S1}")
    print(f'纵向间距（m）= {S2}\n'
          f'锚杆抗拔安全系数K = {K}\n'
          f'锚筋屈服强度标准值fpyk（MPa）= {fpyk}\n'
          f'钢筋与水泥浆、水泥砂浆极限粘结强度标准值fms（MPa）={fms}\n'
          f'锚杆普通段直径D1 = {D1}\n'
          f'锚杆扩大头段直径D2 = {D2}\n'
          f'扩大头上覆土厚度h = {h}\n'
          f'侧压力系数参数α = {a}\n'
          f'锚固体内摩擦角 ={zeta0}\n')
    print('****各层信息输入参数****\n'
          f'锚固体与岩土体的极限粘结强度标准值（kPa）={soil_layer_fmgs}\n'
          f'各层岩土体厚度（m）= {soil_layer_sizes}\n'
          f'各个土层密度gama = {soil_layer_gamas}\n'
          f'各个土层摩擦角度zeta = {soil_layer_zetas}\n'
          f'各个土层粘聚力系数c = {soil_layer_cs}\n')


    sum_h = 0
    edge_index = 0
    for index, s in enumerate(soil_layer_sizes):
        sum_h += s
        if sum_h >= h:
            edge_index = index
            break
    zeta = soil_layer_zetas[edge_index]
    gama = soil_layer_gamas[edge_index]
    c = soil_layer_cs[edge_index]
    sub_soil_layer_fmgs = soil_layer_fmgs[edge_index:]
    sub_soil_layer_sizes = soil_layer_sizes[edge_index:]
    sub_soil_layer_zetas = soil_layer_zetas[edge_index:]
    sub_soil_layer_cs = soil_layer_cs[edge_index:]
    sub_soil_layer_gamas = soil_layer_gamas[edge_index:]
    sub_soil_layer_sizes[0] = sum(soil_layer_sizes[: edge_index + 1]) - h
    Nak = Pk * S1 * S2
    print(f'Step1： Nak = p_k * s1 * s2 \n'
          f'\tNak = {Nak}\n')
    Tak = 1000 * Nak
    print(f'Step2： Tak = 1000 * Nak \n'
          f'\tTak = {Tak}\n')
    Tuk = K * Tak / 1000
    print(f'Step3： Tuk = K * Tak / 1000 \n'
          f'\tTuk = {Tuk}\n')
    A_s1 = 2 * Tak / fpyk
    print(f'Step4： A_s1 = 2 * Tak / fpyk \n'
          f'\tA_s1 = {A_s1}\n')
    d = 0
    for index, aa in enumerate(public_across_area):
        if aa >= A_s1:
            d = public_ds[index]
            break
    print('Step5：根据表格选取对应的公称直径d\n'
          f'\td = {d}\n')
    lD1 = Tuk / (np.pi * d * fms)
    print("Step6：计算lD1\n"
          f"\tlD1 = {lD1}")
    # delta_S = np.tanh(45 + zeta0 / 2) * (D2 / 2 - d / 2) / 1000
    delta_S = np.tan(np.radians(45)+np.radians(zeta0)/2)*(D2/2-d/2)/1000
    print(f"\tΔs = {delta_S}")
    if delta_S<0.5:
        delta_S = 0.5
        print("\tΔs < 0.5, 所以Δs = 0.5")
    LD1 = lD1 + delta_S
    LD1 = max(2, LD1)
    # print("LD1 inti length ", LD1)
    print("\nStep7：计算LD1\n"
          f"\tLD1 = {LD1}\n")
    print("step8 计算ka kp k0 keze")
    # ka = np.tan(np.deg2rad(45 - zeta / 2))
    ka = np.tan((45 - zeta/2) * np.pi/180) ** 2
    # kp = np.tan(np.deg2rad(45 + zeta / 2))
    kp = np.tan(np.radians(45 + zeta / 2)) ** 2
    # k0 = 1 - np.sin(zeta)
    k0 =  1 - np.sin(np.radians(zeta))
    keze = a * ka
    print(f"\tka={ka} \n \tkp={kp} \n \tk0={k0} \n \tζ={keze}\n")

    print("step9 计算PD")
    PD = ((k0 - keze) * kp * gama * h + 2 * c * np.sqrt(kp)) / (1 - keze * kp)
    print(f"\tPD={PD}\n")
    print("下面开始计算Tuk的三个部分(普通端部分，PD项部分和扩大段部分)， 未乘Π")
    tuk_0 = 0
    hh = h
    i = 0
    while hh > 0:
        if hh > soil_layer_sizes[i]:
            tuk_0 += soil_layer_fmgs[i] * D1 * soil_layer_sizes[i] / 1000
            print(f"当前土层序号{i+1}， 当前fmg{soil_layer_fmgs[i]}, 当前普通段在此土层的厚度{soil_layer_sizes[i]}")
            print(f"当前普通段tu累加值{tuk_0}")
        else:
            tuk_0 += soil_layer_fmgs[i] * D1 * hh / 1000
            print(f"当前土层序号{i+1}， 当前fmg{soil_layer_fmgs[i]}, 当前普通段在此土层的厚度{hh}")
            print(f"当前普通段tu累加值{tuk_0}")
        hh -= soil_layer_sizes[i]
        i += 1

    tuk_1 = (D2 ** 2 - D1 ** 2) * PD / 4 / 1000 / 1000
    print(f"PD 部分的 tu值：{tuk_1}")
    tuk2 = cal_tuk2(
        LD1,
        D2,
        sub_soil_layer_fmgs,
        sub_soil_layer_sizes,

    )
    print(f"扩大段的tu初始值{tuk2}")
    cur_tuk = np.pi * (tuk_0 + tuk_1 + tuk2)
    print(f"初始的Tu值={cur_tuk}")
    inter_step = 0.05
    if cur_tuk > Tuk:
        print("初始LD1下计算的tu值已经大于Tuk,无需进行迭代！！")
    i = 1
    while cur_tuk < Tuk:
        LD1 += inter_step
        print(f"---------------{i}---------LD1={LD1}")
        tuk2 = cal_tuk2(
            LD1,
            D2,
            sub_soil_layer_fmgs,
            sub_soil_layer_sizes,
            sub_soil_layer_zetas,
            sub_soil_layer_cs,
            sub_soil_layer_gamas,
        )
        cur_tuk = np.pi * (tuk_0 + tuk_1 + tuk2)

    print("LD1 最终设计长度 ", LD1)

    #step 11
    n = (1.1 * A * Pk) / Nak
    print("最终设计方案")
    print(f"锚杆数量={n}\n普通段长度={h}\n普通段直径={D1}\n扩大段长度{LD1}\n扩大段长直径{D2}筋公称直径={d}\n")
    return n, h, D1, LD1, D2, d



import functools
class Product:
    def __init__(self, *iterables):
        self.iters = iterables
        self.lengths = [i.__len__() for i in self.iters]
        self.l = functools.reduce(lambda x, y: x * y, self.lengths)

    def __getitem__(self, index):
        idxs = []
        if index >= self.l:
            raise StopIteration

        for l in reversed(self.lengths):
            tmp = index // l
            i = int(index - tmp * l)
            idxs.append(i)
            index = tmp
        res = [it[idx] for it, idx in zip(self.iters, idxs[::-1])]
        return res

    def __len__(self):
        return self.l


class AnchorDesign(object):
    def __init__(self,
             A=1281.4,
             Pk=46,
             S1=3.9,
             S2=3.9,
             K=2,
             fpyk=1080,
             fms=2.2,
             h=5,
             a=0.85,
             D1=200,
             D2=500,
             zeta0=35,
             soil_layer_fmgs=[50, 90, 260, 260, 260],
             soil_layer_sizes=[1.3, 2, 1, 2.5, 4.9],
             soil_layer_zetas=[20, 25, 30, 35, 36],
             soil_layer_cs=[0, 0, 0, 0, 260],
             soil_layer_gamas=[19.5, 20.5, 21, 22, 23],
             M=4632,
             N=500,
             design_type=1,
                 pwd=None

             ):
        #1: 拉压-扩大头，初始ld+deltaS-> LD
        #2: 拉压-等直, 初始LD
        #3: 压力-扩大头, 没有初始LD
        #4: 压力-等直, 没有初始LD
        self.delta_S = None
        self.word_lD1 = None
        self.word_As = None
        self.word_Tuk = None
        self.A = A
        self.PK = Pk
        self.S1 = S1
        self.S2 = S2
        self.K = K
        self.fpyk = fpyk
        self.fms = fms
        self.h = h
        self.a = a
        self.D1 = D1
        self.D2 = D2
        self.zeta0 = zeta0
        self.fmgs = soil_layer_fmgs
        self.sizes = soil_layer_sizes
        self.zetas = soil_layer_zetas
        self.cs = soil_layer_cs
        self.gamas = soil_layer_gamas
        self.N = N
        self.M = M
        self.type = design_type
        self.init_split_index = 0
        self.sub_size_0 = self.sizes
        self.sub_size_1 = self.sizes
        self.sub_fmgs_0 = self.fmgs
        self.sub_fgms_1 = self.fmgs

        self.sub_fmgs = self.fmgs

        self.zeta = soil_layer_zetas[self.init_split_index]
        self.gama = soil_layer_gamas[self.init_split_index]
        self.c = soil_layer_cs[self.init_split_index]

        if self.type in [1, 3]:
            self.init_split_index, self.sub_size_0, self.sub_size_1 = self.split_layer(self.h, self.sizes)
            self.sub_fmgs_0 = self.fmgs[: self.init_split_index + 1]
            self.sub_fgms_1 = self.fmgs[self.init_split_index: ]
            self.zeta = soil_layer_zetas[self.init_split_index]
            self.gama = soil_layer_gamas[self.init_split_index]
            self.c = soil_layer_cs[self.init_split_index]
        self.target_tuk = 0
        self.d = 0
        # 当锚杆类型为2，4即等直型时候，只有一个锚杆长度，
        # 当锚杆类型为1， 3即扩大型的时候，分普通段和扩大段长度
        self.target_l = 0
        self.target_l2 = 0
        self.LD = 5
        self.n = 0
        self.opt_dict = {}
        self.opt_space = Product(*[[180, 200, 300], [400, 500, 600], np.arange(4, 10, 0.1)])
        if self.type in [2, 4]:
            self.opt_space = Product(*[[150, 180, 200, 300, 400, 500], np.arange(4, 15, 0.1)])
        self.pwd = pwd
        self.log(f"设计类型：{self.type}")
        self.delta_S = 0
        self.A_s1 = (0, 0)
        self.target_min_ld_without_delta_S = 0
        self.validation_total_args = []
        self.strength_validation_circle_kwargs = {}
        self.validation_chong_qie_cheng_zai_li_kwargs = {}
        self.validation_jubu_shouya_kwargs = {}
        self.validation_shou_ya_chengzai_li_kwargs = {}
        self.PD = -1
        self.min_tuk = 0
        self.tuk_j = 0

    def log(self, log):
        return

        if "计算过程.txt" not in os.listdir(self.pwd):

            os.system(f"echo 计算过程 >> {os.path.join(self.pwd, '计算过程.txt')}")
        os.system(f"echo {log} >> {os.path.join(self.pwd, '计算过程.txt')}")
        pass

    def split_layer(self, h, soil_layer_sizes):
        # 将土层分成两组，返回两个子土层数组
        sum_h = 0
        edge_index = 0
        for index, s in enumerate(soil_layer_sizes):
            sum_h += s
            if sum_h >= h:
                edge_index = index
                break
        sub_layer0 = soil_layer_sizes[:edge_index + 1]
        sub_layer0[-1] = h - sum(sub_layer0[:-1])
        sub_layer1 = soil_layer_sizes[edge_index:]
        sub_layer1[0] = sum(soil_layer_sizes[:edge_index + 1]) - h
        return edge_index, sub_layer0, sub_layer1

    def general(self):
        Pk = self.PK
        S1 = self.S1
        S2 = self.S2
        K = self.K
        fpyk = self.fpyk
        fms = self.fms
        D2 = self.D2
        zeta0 = self.zeta0
        with_delta_S = True
        Nak = 1.05 * Pk * S1 * S2
        # print(f'Step1： Nak = p_k * s1 * s2 \n'
        #       f'\tNak = {Nak}\n')
        Tak = 1000 * Nak

        # print(f'Step2： Tak = 1000 * Nak \n'
        #       f'\tTak = {Tak}\n')
        Tuk = K * Tak / 1000
        self.word_Tuk = Tuk
        self.log(f"Nak = 1.05 * Pk * S1 * S2 = {Nak}")
        self.log(f"tak = {Tak}, Tuk={Tuk}")
        self.target_tuk = Tuk

        # print(f'Step3： Tuk = K * Tak / 1000 \n'
        #       f'\tTuk = {Tuk}\n')
        A_s1 = 2 * Tak / fpyk
        self.word_As = A_s1
        # print(f'Step4： A_s1 = 2 * Tak / fpyk \n'
        #       f'\tA_s1 = {A_s1}\n')
        d = 0
        real_A_s1 = 0

        for index, aa in enumerate(public_across_area):
            if aa >= A_s1:
                d = public_ds[index]
                real_A_s1 = public_across_area[index]
                break
        self.A_s1 = (A_s1, real_A_s1)
        self.d = d
        self.log(f"选择的钢筋公称直径是d={d}")

        lD1 = round(Tuk / (np.pi * d * fms), 6)#只适用于拉压型号
        self.target_min_ld_without_delta_S = lD1
        self.word_lD1 = lD1
        self.log(f"lD1=Tuk / (3.14 * d * fms) = {lD1}")
        if self.type == 2:
            self.LD = lD1

        # delta_S = np.tanh(45 + zeta0 / 2) * (D2 / 2 - d / 2) / 1000
        delta_S = np.tan(np.radians(45)+np.radians(zeta0)/2)*(D2/2-d/2)/1000  #粘结段长度
        self.delta_S = delta_S

        if delta_S<0.5:
            delta_S = 0.5
            self.delta_S = delta_S
        if self.type in [1]:
            self.log(f"delta_S = np.tan(np.radians(45)+np.radians(zeta0)/2)*(D2/2-d/2)/1000={delta_S}")
            LD1 = lD1 + self.delta_S #只适用于扩大头拉压型
            self.log(f"LD1 = lD1 + delta_S = {LD1}")
        else:
            LD1 = lD1

        if self.type in [1, 2]:
            LD1 = max(2, LD1)
            self.LD = LD1
            self.log(f"LD 不足2m, 强制为2m")
        # elif self.type == [3,4]: #此处有误， 6m是type=2最终迭代总长的最小值
        #     LD1 = max(6, LD1)
        #     self.LD = LD1
        #     self.log(f"LD 不足6m, 强制为6m")
        else:
            self.LD = self.h#
            self.log(f"LD = {self.h}")
        if self.type == 3:
            self.LD = min(4.5,sum(self.sizes) - self.h - 1)
        self.LD = round(self.LD, 8)
        self.log(f"最终初始LD={self.LD}")

    def cal_pd(self, zeta, gama, h, c, a):
        ka = np.tan((45 - zeta / 2) * np.pi / 180) ** 2
        self.log(f"ka = np.tan((45 - zeta / 2) * np.pi / 180) ** 2 = {ka}")
        # kp = np.tan(np.deg2rad(45 + zeta / 2))
        kp = np.tan(np.radians(45 + zeta / 2)) ** 2
        self.log(f"kp = np.tan(np.radians(45 + zeta / 2)) ** 2 = {kp}")
        # k0 = 1 - np.sin(zeta)
        k0 = 1 - np.sin(np.radians(zeta))
        self.log(f"1 - np.sin(np.radians(zeta)) = {k0}")
        keze = a * ka
        self.log(f"keze = a * ka = {keze}")
        # print(f"\tka={ka} \n \tkp={kp} \n \tk0={k0} \n \tζ={keze}\n")

        # print("step9 计算PD")
        PD = ((k0 - keze) * kp * gama * h + 2 * c * np.sqrt(kp)) / (1 - keze * kp)
        self.log(f"PD = ((k0 - keze) * kp * gama * h + 2 * c * np.sqrt(kp)) / (1 - keze * kp) = {PD}")
        return PD

    def cal_tuk2(
            self,
            LD,
            D2,
            soil_layer_fmgs,
            soil_layer_sizes,

    ):
        tuk2 = 0
        lldd = LD
        i = 0
        while lldd > 0:
            if lldd >= soil_layer_sizes[i]:
                tuk2 += soil_layer_fmgs[i] * D2 * soil_layer_sizes[i] / 1000
            else:
                tuk2 += soil_layer_fmgs[i] * D2 * lldd / 1000
            lldd -= soil_layer_sizes[i]
            i += 1
        return tuk2

    def iter(self):
        pass

    def cal_total_tuk(self):
        self.log(f"计算当前参数下的tuk")
        if self.type in [1, 3]:
            self.log(f"计算扩大头PD 部分")
            PD = self.cal_pd(self.zeta, self.gama, self.h, self.c, self.a)
            self.PD = PD
            tuk_3 = (self.D2** 2 - self.D1 ** 2) * PD / 4 / 1000 / 1000
            self.log(f"tuk_3 = (self.D2** 2 - self.D1 ** 2) * PD / 4 / 1000 / 1000 = {tuk_3}")

            tuk_0 = self.cal_tuk2(self.h, self.D1, self.sub_fmgs_0, self.sub_size_0)
            self.log(f"tuk_0 = self.cal_tuk2(self.h, self.D1, self.sub_fmgs_0, self.sub_size_0)={tuk_0}")
            tuk_1 = self.cal_tuk2(self.LD, self.D2, self.sub_fgms_1, self.sub_size_1)
            self.log(f"tuk_1 = self.cal_tuk2(self.h, self.D1, self.sub_fmgs_0, self.sub_size_0)={tuk_1}")

            cur_tuk = np.pi * (tuk_0 + tuk_1 + tuk_3)
            self.log( f"cur_tuk = np.pi * (tuk_0 + tuk_1 + tuk_3) = {cur_tuk}")
        else:
            cur_tuk = np.pi * self.cal_tuk2(self.LD, self.D1, self.fmgs, self.sizes)
            self.log(f"cur_tuk = np.pi * self.cal_tuk2(self.LD, self.D1, self.fmgs, self.sizes) = {cur_tuk}")
        return cur_tuk

    def design(self):
        # 第一步，计算公共用到的变量，包括目标Tu值 Tuk，钢筋直径d，以及可能存在的初始LD值
        self.general()
        # 第二步 对于扩大头类型的锚杆，tuk由三部分贡献而来：小端tuk 大头段tuk，PD项 tuk
        # 先计算PD项
        self.log("-----------------------第1轮迭代-----------------------")
        cur_tuk = self.cal_total_tuk()

        last_LD = self.LD
        iter_step = 0.1
        self.n = math.ceil(self.A / (self.S1 * self.S2))
        i = 2
        while True:
            if cur_tuk > self.target_tuk:
                if self.type in [1, 2]:
                    break
                last_LD = self.LD
                self.LD -= iter_step
                if self.type in [1, 3]:
                    if self.LD < 2:
                        self.LD += iter_step
                        break
                if self.type in [2, 4]:
                    if self.LD < 6:
                        self.LD += iter_step
                        break
                cur_tuk = self.cal_total_tuk()

                if cur_tuk < self.cal_total_tuk():
                    self.LD = last_LD
                    break
            elif cur_tuk < self.target_tuk:
                last_LD = self.LD
                self.LD += iter_step
                cur_tuk = self.cal_total_tuk()
                if cur_tuk > self.target_tuk:
                    break
            self.log(f"-----------------------第{i}轮迭代-----------------------")
            i += 1
            self.log(f"迭代后当前tuk={cur_tuk}, 目标tuk={self.target_tuk}")
        if self.type in [1, 3]:
            self.LD = max(self.LD, 2)
        else:
            if self.type == 2 and self.LD < 6:
                pass
                self.target_min_ld_without_delta_S = 4
            self.LD = max(self.LD, 6)
        cur_tuk = self.cal_total_tuk()
        self.tuk_j = cur_tuk
    def copy(self):
        obj = AnchorDesign()
        import copy
        for k, v in copy.deepcopy(self.__dict__.items()):
            setattr(obj, k, v)
        return

    def optimize(self):
        if self.type in [1, 3]:
            for p in self.opt_space:
                try:
                    D1, D2, h = p
                    self.D1 = D1
                    self.D2 = D2
                    self.h = h
                    #由于变化后，普通段与扩大头分割面所在的位置可能会变化所以需要重新划分土层
                    self.init_split_index, self.sub_size_0, self.sub_size_1 = self.split_layer(self.h, self.sizes)
                    self.sub_fmgs_0 = self.fmgs[: self.init_split_index + 1]
                    self.sub_fgms_1 = self.fmgs[self.init_split_index:]
                    self.zeta = self.zetas[self.init_split_index]
                    self.gama = self.gamas[self.init_split_index]
                    self.c = self.cs[self.init_split_index]

                    self.design()
                    p.append(self.LD)
                    p.append(self.n)
                    p.append(self.delta_S)
                    pp = []
                    for v in [self.n, self.d, self.D1, self.h, self.D2, self.LD, self.cal_total_tuk()]:
                        pp.append(v)
                    self.opt_dict[self.cal_total_cost()] = tuple(pp)
                except Exception as e:
                    continue
        else:
            for p in self.opt_space:
                try:
                    D1, h = p
                    self.D1 = D1
                    self.h = h
                    self.design()
                    p[1] = self.LD
                    p.append(self.n)
                    pp = []
                    if self.type == 2:
                        for v in [self.n, self.d, self.D1, self.LD - self.target_min_ld_without_delta_S, self.target_min_ld_without_delta_S, self.cal_total_tuk()]:
                            pp.append(v)
                    else:
                        for v in [self.n, self.d, self.D1, self.LD, self.cal_total_tuk()]:
                            pp.append(v)

                    self.opt_dict[self.cal_total_cost()] = tuple(pp)
                except Exception as e:
                    #此处应该在statuts bar告知用户发生这个参数下了土层不够
                    continue

    def cal_total_cost(self):

        if self.type in [1, 3]:
            a = 1.9625*np.pi*(self.d/1000)**2*(self.LD + self.h) * self.M * self.n
            b = np.pi / 4 * ((self.D1/1000) ** 2 * self.h +  (self.D2/1000)**2 * self.LD) * self.N * self.n
            return math.ceil(a + b)
        elif self.type in [2, 4]:
            a = 1.9625 * np.pi * (self.d/1000) ** 2 * self.LD * self.M * self.n
            b = np.pi / 4 * (self.D1/1000) ** 2 * self.LD * self.N * self.n
            return math.ceil(a + b)
        pass

    def validation_total(self, gk, rk, wk, nwk, kw):
        self.validation_total_args = (gk, rk, wk, nwk,kw)

        a = (gk + rk + wk ) / nwk
        # b = kw * -1
        b = kw
        return a, b, a > b

    def strength_validation_circle(self, **kwargs):
        self.strength_validation_circle_kwargs = kwargs
        if kwargs.get("type", 1) == 1:
            f = kwargs.get("f")  # 锚固板钢材抗拉强度设计值
            R = kwargs.get("R")  # 锚固板外半径
            nd = kwargs.get("nd")  # 锚杆轴向拉力设计值
            t = kwargs.get("t")  # 锚固板厚度（mm）
            sn = kwargs.get("sn")  # 六角螺母对边宽度（mm）
            hn = kwargs.get("hn")  # 钢筋螺纹高度
            d = kwargs.get("d")  #钢筋直径
            sigama = kwargs.get("sigama", 0.75)  # 锚固板内孔壁与锚筋螺纹之间的空隙（mm）

            a = kwargs.get("a") #方形锚固板边长
            r = 0.5 * d + hn + sigama
            r1 = 0.5 * sn - 2.0

            shape = kwargs.get("shape", "circle")
            if shape == "circle":

                p = nd / (np.pi * (R ** 2 - r ** 2)) * 1000
                am = (2 * R ** 3 - 3 * R ** 2 * r1 + r1 ** 3) / r1
                ret0 = t >= math.sqrt(am * p / f)
                # ret0 = True

                return t, math.sqrt(am * p / f), ret0
            else:
                p = nd / (a**2 - np.pi*r**2) * 1000
                M1 = 2 * np.pi * p * (a**3 / 24 - a **2*r1/8 + r1**3/6)
                S1 = 0.21 * a**2
                ls = 0.55 * a
                M2 = S1 * p * ( ls - r1)
                M = M1 + M2
                ret0 =  t >= math.sqrt(3 * M / (np.pi*r1*f))
                # ret0 = True
                return t, math.sqrt(3 * M / (np.pi*r1*f)), ret0

    def validation_chong_qie_cheng_zai_li(self, **kwargs):
        self.validation_chong_qie_cheng_zai_li_kwargs = kwargs

        nd = kwargs.get("nd")
        psk = kwargs.get("psk")
        abt = kwargs.get("abt")
        beta_h = kwargs.get("beta_h")
        ft = kwargs.get("ft")
        h0 = kwargs.get("h0")
        shape = kwargs.get("shape", "circle")
        td = 1.1 * nd
        if shape == "circle":
            R = kwargs.get("R")
            um = (2 * R + h0) * np.pi
            ret1 = td - psk * abt <= 0.7 * beta_h * ft * um * h0
            # ret1 = True
            return td - psk * abt, 0.7 * beta_h * ft * um * h0, ret1
        elif shape == "square":
            a = kwargs.get("a")
            um = 4 * (a + h0)
            ret1 = td - psk * abt <= 0.7 * beta_h * ft * um * h0
            # ret1 = True
            return td - psk * abt, 0.7 * beta_h * ft * um * h0, ret1

    def validation_shou_ya_chengzai_li(self, **kwargs):
        self.validation_shou_ya_chengzai_li_kwargs = kwargs
        A_D = kwargs.get("A_D")
        A_I = kwargs.get("A_I")
        f_c = kwargs.get("f_c")
        A_ln = kwargs.get("A_ln")
        nd = kwargs.get("nd")

        # if self.type == 1:
        td = 1.1 * nd
        target = 0.85 * math.sqrt(A_D / A_I) * f_c * A_ln
        # return target, True
        return target, td, td <= target

    def validation_jubu_shouya(self, **kwargs):
        self.validation_jubu_shouya_kwargs = kwargs
        ing = kwargs.get("ing")
        tuk = kwargs.get("tuk")
        apn = kwargs.get("apn")
        fck = kwargs.get("fck")
        # return  ing * apn * fck, True
        return  ing * apn * fck, tuk <= ing * apn * fck

        pass
    def validation_strength_base(self):
        pass
    def strength_validation(self, **kwargs):
        type = kwargs.get("type", 1)
        if type == 1:
            pass

        # if type == 1 and shape == "circle":
        #     pass
            # t = kwargs.get("t")
            # sn = kwargs.get("sn")
            # hn = kwargs.get("hn")
            # sigama = kwargs.get("sigama", 0.75)
            # r = 0.5 * self.d + hn + sigama
            # p = nd / (np.pi * (R**2 - r**2))
            # r1 = 0.5 * sn - 2.0
            # am = (2 * R**3 - 3 * R**2 * r1 + r1**3) / r1
            # ret0 =  t >= math.sqrt(am * p / f)
            #
            # td = 1.1 * nd
            # psk = kwargs.get("psk")
            # abt = kwargs.get("abt")
            # beta_h = kwargs.get("beta_h")
            # ft = kwargs.get("ft")
            # h0 = kwargs.get("h0")
            # um = (2 * R + h0) * np.pi
            # ret1 = td - psk * abt <= 0
            # .7*beta_h*ft * um * h0
            # return ret0 and ret1

        # if type == 1  and shape == "square":
        #     nd = kwargs.get("nd")
        #     r = kwargs.get("r")
        #     r1 = kwargs.get("r1") # 不知道是输入参数还是继承上面圆形的步骤
        #
        #     a = kwargs.get("a")
        #     p = nd / (a**2 - np.pi*r**2)
        #     M1 = 2 * np.pi * p * (a**3 / 24 - a **2*r/8 + r1**3/6)
        #     S1 = 0.21 * a**2
        #     ls = 0.55 * a
        #     M2 = S1 * p * ( ls - r1)
        #     M = M1 + M2
        #     t = kwargs.get("t")
        #     ret0 =  t >= math.sqrt(3 * M / (np.pi*r1*f))


            # td = 1.1 * nd
            # psk = kwargs.get("psk")
            # abt = kwargs.get("abt")
            # beta_h = kwargs.get("beta_h")
            # ft = kwargs.get("ft")
            # h0 = kwargs.get("h0")
            # um = 4 * (a + h0)
            # ret1 = td - psk * abt <= 0.7 * beta_h * ft * um * h0
            # return ret0 and ret1

            pass





        pass

    def anchor_node_bearing_capacity(self):
        if self.type == 1:

            pass
        pass


if __name__ == "__main__":
    # anchor_design_1(
    #     A=1281.4,
    #     Pk=46,
    #     S1=3.9,
    #     S2=3.9,
    #     K=2,
    #     fpyk=1080,
    #     fms=2.2,
    #     h=5,
    #     a=0.85,
    #     D1=200,
    #     D2=500,
    #     zeta0=35,
    #     soil_layer_fmgs=[50, 90, 260, 260, 260],
    #     soil_layer_sizes=[1.3, 2, 1, 2.5, 4.9],
    #     soil_layer_zetas=[20, 25, 30, 35, 36],
    #     soil_layer_cs=[0, 0, 0, 0, 260],
    #     soil_layer_gamas=[19.5, 20.5, 21, 22, 23]
    # )
    d = AnchorDesign(design_type=1, soil_layer_sizes=[1.3, 2, 1, 2.5, 20], pwd="./")
    d.design()
    kwargs = {"A_D": 0.5, "A_I": 0.4, "f_c":30000, "A_ln": 0.35, "nd": 9050}
    A_D = kwargs.get("A_D")
    A_I = kwargs.get("A_I")
    f_c = kwargs.get("f_c")
    A_ln = kwargs.get("A_ln")
    nd = kwargs.get("nd")
    print(d.validation_shou_ya_chengzai_li(**kwargs))
